package cz.pecinovsky.english.pojj.adv_demo.zaklad_pavlickove;

import java.util.Set;
import java.util.HashSet;

/**
 *  Trida Mistnost - popisuje jednotlivou místnost ve hře
 *
 *  Tato třída je součástí jednoduché textové hry.
 *
 *  "Mistnost" reprezentuje jedno místo (místnost, prostor, ..) ve scénáři
 *  hry. Místnost může mít sousední místnosti připojené přes východy. Pro
 *  každý východ si místnost ukládá odkaz na sousedící místnost (instanci
 *  třídy Mistnost).
 *
 *@author     Michael Kolling, Lubos Pavlicek, Jarmila Pavlickova
 *@created    říjen 2008 (poslední změny)
 */

class Mistnost
{
    private String nazev;
    private String popis;
    private Set<Mistnost> vychody;   // obsahuje sousední místnosti

    /**
     * Vytvoření místnosti (pojmenovaný prostor) se zadaným popisem, např.
     * "kuchyň", "hala", "trávník před domem"
     *
     *@param  nazev     Jméno místnosti, jednoznačný identifikátor, jedno slovo nebo víceslovný název bez .
     *@param  popis     Popis místnosti.
     */
    public Mistnost(String nazev, String popis) {
        this.nazev = nazev;
        this.popis = popis;
        vychody = new HashSet<Mistnost>();
    }

    /**
     * Definuje východ z místnosti (sousední/vedlejsi místnost). Vzhledem k tomu, že je použit
     * Set pro uložení východů, může být sousední místnost uvedena pouze jednou
     * (tj. nelze mít dvoje dveře do stejné sousední místnosti). Druhé zadání
     * stejné místnosti tiše přepíše předchozí zadání (neobjeví se žádné chybové hlášení).
     * Lze zadat též cestu ze do sebe sama.
     *
     * @param vedlejsi mistnost, ktera sousedi s aktualni mistnosti.
     *
     */
    public void setVychod(Mistnost vedlejsi) {
        vychody.add(vedlejsi);
    }

    /**
     * Metoda equals pro porovnání dvou místností. Překrývá se metoda equals ze třídy Object.
     * Dvě místnosti jsou shodné, pokud mají stejné jméno.
     * Tato metoda je důležitá z hlediska správného fungování seznamu místností (Set).
     *
     * Bližší popis metody equals je u třídy Object.
     *
     *@param   o  object, který se má porovnávat s aktuálním
     *@return     hodnotu true, pokud zadaná místnost má stejné jméno, jinak false
     */

    public boolean equals (Object o) {
        if (o instanceof Mistnost) {
            Mistnost druha = (Mistnost)o;
            return nazev.equals(druha.nazev);
        }
        else {
            return false;
        }
    }

    /**
     * metoda hashCode vraci ciselny identifikator instance, ktery se pouziva pro optimalizaci ukladani
     * v dynamickych datovych strukturach. Pri prekryti metody equals je potreba prekryt i metodu hashCode.
     * Podrobny popis pravidel pro vytvareni metody hashCode je u metody hashCode ve tride Object
     */

    public int hashCode() {
        return nazev.hashCode();
    }


    /**
     * Vrací jméno místnosti (bylo zadáno při vytváření místnosti jako
     * parametr konstruktoru)
     *
     *@return    Jméno místnosti
     */
    public String getNazev() {
        return nazev;
    }

    /**
     * Vrací "dlouhý" popis místnosti, který může vypadat následovně:
     *      Jsi v mistnosti/prostoru vstupni hala budovy VSE na Jiznim meste.
     *      vychody: chodba bufet ucebna
     *
     *@return    Dlouhý popis místnosti
     */
    public String dlouhyPopis() {
        return "Jsi v mistnosti/prostoru " + popis + ".\n" + seznamVychodu();
    }

    /**
     * Vrací textový řetězec, který popisuje sousední místnosti (východy) například:
     * "vychody: hala ".
     *
     *@return    Seznam sousedních místností (východů)
     */
    private String seznamVychodu() {
        String vracenyText = "vychody:";
        for (Mistnost sousedni : vychody) {
             vracenyText += " " + sousedni.getNazev();
        }
        return vracenyText;
    }

    /**
     * Vrací místnost, která sousedí s aktuální místností a jejíž jméno je zadáno
     * jako parametr. Pokud místnost s udaným jménem nesousedí s aktuální místností,
     * vrací se hodnota null.
     *
     *@param  jmenoSousedni  Jméno sousední místnosti (východu)
     *@return            Místnost, která se nachází za příslušným východem, nebo
     *                   hodnota null, pokud místnost zadaného jména není sousedem.
     */
    public Mistnost sousedniMistnost(String jmenoSousedni) {
        if (jmenoSousedni == null) {
            return null;
        }
        for ( Mistnost sousedni : vychody ){
            if (sousedni.getNazev().equals(jmenoSousedni)) {
                return sousedni;
            }
        }
        return null;  // místnost nenalezena
    }

}

